package com.ctg.behavior.calc.impala.calculator;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ctg.behavior.api.CtCalcStatus;
import com.ctg.behavior.calc.common.CtSQLParam;
import com.ctg.behavior.calc.impala.CtCalculator;
import com.ctg.behavior.calc.impala.builder.userbehavior.CtUSCalcResultBuilder;
import com.ctg.behavior.calc.impala.builder.userbehavior.CtUSReportBuilder;
import com.ctg.behavior.calc.impala.engine.ImpalaSQLEngine;
import com.ctg.behavior.calc.impala.report.userbehavior.CtUSReport;
import com.ctg.behavior.calc.impala.transfer.CtTotalTransfer;
import com.ctg.behavior.calc.impala.transfer.userbehavior.CtUSTransfer;
import com.ctg.behavior.calc.impala.utils.CtCalculatorUtils;
import com.ctg.behavior.client.impala.common.CtQueryResult;
import com.ctg.behavior.common.CtgRowsData;
import com.ctg.behavior.common.calc.CtCalcBody;
import com.ctg.behavior.common.calc.CtCalcResult;
import com.ctg.behavior.common.calc.CtCalcTotal;
import com.ctg.behavior.common.consts.CtCalcConsts;
import com.ctg.behavior.common.consts.CtFieldConsts;
import com.ctg.behavior.common.usersequence.CtUSCalcBody;
import com.ctg.behavior.common.usersequence.CtUSCalcData;
import com.ctg.behavior.common.usersequence.CtUSCalcResult;
import com.ctg.behavior.utils.CtDateUtils;
import com.ctg.behavior.utils.CtStatusUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class CtUSCalculator implements CtCalculator {

	@Autowired
	private CtUSReportBuilder usReportBuilder;
	@Autowired
	private CtUSTransfer usTransfer;
	@Autowired
	private ImpalaSQLEngine sqlEngine;
	@Autowired
	private CtUSCalcResultBuilder usResultBuilder;
	@Autowired
	private CtTotalTransfer totalTransfer;

	/****************************************************************
	 * @apiNote: 1.
	 */
	@Override
	public CtCalcResult doCalculator(CtCalcBody calcBody) {
		CtUSCalcResult calcResult = new CtUSCalcResult();
		if (!(calcBody instanceof CtUSCalcBody)) {
			log.error("calcBody={}", calcBody.getClass());
			CtStatusUtils.fillStatus(calcResult, CtCalcStatus.BodyNoMatch);
			return calcResult;
		}
		CtUSCalcBody usCalcBody = (CtUSCalcBody) calcBody;

		CtgRowsData<CtUSCalcData> calcData = new CtgRowsData<>();
		calcResult.setValue(calcData);

		log.info("doBuilder-start: {}", CtDateUtils.getCurrentDateSSS());
		List<CtUSReport> usReports = usReportBuilder.doBuilder(usCalcBody);
		log.info("doBuilder-end: {}", CtDateUtils.getCurrentDateSSS());

		log.info("time - start: {}", CtDateUtils.getCurrentDateSSS());
		for (CtUSReport usReport : usReports) {
			String transferedSQL = usTransfer.doTransfer(usReport, CtSQLParam.createParam());
			log.info("one-reportSql={}", transferedSQL);
			CtQueryResult queryResult = sqlEngine.doQuery("", transferedSQL);
			log.info("one-queryResult={}", JSON.toJSONString(queryResult));

			CtCalculatorUtils.fillCalcResult(calcResult, queryResult);
			if (!calcResult.getSuccess()) {
				log.error(queryResult.getCode());
				break;
			}
			
			if (CtCalcConsts.LOAD_TYPE_DETAIL.equalsIgnoreCase(usCalcBody.getLoadType())) {
				CtCalcTotal calcTotal = new CtCalcTotal();
				calcTotal.setDetailSQL(transferedSQL);
				String totalSQL = totalTransfer.doTransfer(calcTotal, CtSQLParam.createParam());
				CtQueryResult totalResult = sqlEngine.doQuery("", totalSQL);
				log.info("totalResult={}", JSON.toJSONString(totalResult));
				Integer countTotal = 0;
				if(!totalResult.getRows().isEmpty()) {
					countTotal = Integer.valueOf(totalResult.getRows().get(0).get(CtFieldConsts.FIELD_KEY_TOTAL).toString());
				}
				usReport.setTotal(countTotal);
			}
			
			calcData = usResultBuilder.doBuilder(calcData, queryResult.getRows(), usReport);
			log.info("one-calcData={}", JSON.toJSONString(calcData));
		}
		log.info("time - end: {}", CtDateUtils.getCurrentDateSSS());

		return calcResult;
	}

}
